home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 19 / Amiga Plus Leser CD 19.iso / Tools / Freeware / Swf_Player / Lib / adpcm.cc next >
Encoding:
C/C++ Source or Header  |  2002-11-17  |  4.5 KB  |  236 lines

  1.  
  2. #include "swf.h"
  3.  
  4. #ifdef RCSID
  5. static char *rcsid = "$Id: adpcm.cc,v 1.1 1998/08/31 21:52:39 olivier Exp $";
  6. #endif
  7.  
  8. // This file has been rearranged from the code posted
  9. // on news:forums.macromedia.com by Jonathan Gay.
  10. // Courtesy of Macromedia
  11.  
  12. //
  13. // ADPCM tables
  14. //
  15.  
  16. static const int indexTable2[2] = {
  17.     -1, 2,
  18. };
  19.  
  20. // Is this ok?
  21. static const int indexTable3[4] = {
  22.     -1, -1, 2, 4,
  23. };
  24.  
  25. static const int indexTable4[8] = {
  26.     -1, -1, -1, -1, 2, 4, 6, 8,
  27. };
  28.  
  29. static const int indexTable5[16] = {
  30.  -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16,
  31. };
  32.  
  33. static const int* indexTables[] = {
  34.  indexTable2,
  35.  indexTable3,
  36.  indexTable4,
  37.  indexTable5
  38. };
  39.  
  40. static const int stepsizeTable[89] = {
  41.     7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
  42.     19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
  43.     50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
  44.     130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
  45.     337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
  46.     876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
  47.     2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
  48.     5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
  49.     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
  50. };
  51.  
  52. long
  53. Adpcm::GetBits(int n)
  54. {
  55.     if ( bitPos < n ) FillBuffer();
  56.  
  57.     assert(bitPos >= n);
  58.  
  59.     long v = ((unsigned long)bitBuf << (32-bitPos)) >> (32-n);
  60.     bitPos -= n;
  61.  
  62.     return v;
  63. }
  64.  
  65. long
  66. Adpcm::GetSBits(int n)
  67. {
  68.     if ( bitPos < n ) FillBuffer();
  69.  
  70.     assert(bitPos >= n);
  71.  
  72.     long v = ((long)bitBuf << (32-bitPos)) >> (32-n);
  73.     bitPos -= n;
  74.  
  75.     return v;
  76. }
  77.  
  78. //
  79. // The Decompressor
  80. //
  81.  
  82. // Constructor
  83. Adpcm::Adpcm(unsigned char *buffer, long isStereo)
  84. {
  85.     stereo = isStereo;
  86.     src = buffer;
  87.  
  88.     nBits = 0; // flag that it is not inited
  89.     nSamples = 0;
  90.  
  91.     bitPos = 0;
  92.     bitBuf = 0;
  93. }
  94.  
  95. void
  96. Adpcm::FillBuffer()
  97. {
  98.     while ( bitPos <= 24 /*&& srcSize > 0*/ ) {
  99.         bitBuf = (bitBuf<<8) | *src++;
  100.         bitPos += 8;
  101.     }
  102. }
  103.  
  104. void
  105. Adpcm::Decompress(short *dst, long n)
  106. {
  107.     if ( nBits == 0 ) {
  108.         // Get the compression header
  109.         nBits = (int)GetBits(2)+2;
  110.     }
  111.  
  112.     const int* indexTable = indexTables[nBits-2];
  113.     int k0 = 1 << (nBits-2);
  114.     int signmask = 1 << (nBits-1);
  115.  
  116.     if ( !stereo ) {
  117.         // Optimize for mono
  118.         long        vp = valpred[0]; // maybe these can get into registers...
  119.         int        ind = index[0];
  120.         long        ns = nSamples;
  121.  
  122.         while ( n-- > 0 ) {
  123.             ns++;
  124.  
  125.             if ( (ns & 0xFFF) == 1 ) {
  126.                 // Get a new block header
  127.                 *dst++ = (short)(vp = GetSBits(16));
  128.  
  129.                 ind = (int)GetBits(6); // The first sample in a block does not have a delta
  130.             } else {
  131.                 // Process a delta value
  132.                 int delta = (int)GetBits(nBits);
  133.  
  134.                 // Compute difference and new predicted value
  135.                 // Computes 'vpdiff = (delta+0.5)*step/4'
  136.                 int step = stepsizeTable[ind];
  137.                 long vpdiff = 0;
  138.                 int k = k0;
  139.  
  140.                 do {
  141.                     if ( delta & k )
  142.                     vpdiff += step;
  143.                     step >>= 1;
  144.                     k >>= 1;
  145.                 } while ( k );
  146.  
  147.                 vpdiff += step; // add 0.5
  148.  
  149.                 if ( delta & signmask ) // the sign bit
  150.                     vp -= vpdiff;
  151.                 else
  152.                     vp += vpdiff;
  153.  
  154.                 // Find new index value
  155.                 ind += indexTable[delta&(~signmask)];
  156.  
  157.                 if ( ind < 0 )
  158.                     ind = 0;
  159.                 else if ( ind > 88 )
  160.                     ind = 88;
  161.  
  162.                 // clamp output value
  163.                 if ( vp != (short)vp )
  164.                     vp = vp < 0 ? -32768 : 32767;
  165.  
  166.                 /* Step 7 - Output value */
  167.                 *dst++ = (short)vp;
  168.             }
  169.         }
  170.  
  171.         valpred[0] = vp;
  172.         index[0] = ind;
  173.         nSamples = ns;
  174.  
  175.     } else {
  176.         int sn = stereo ? 2 : 1;
  177.  
  178.         // Stereo
  179.         while ( n-- > 0 ) {
  180.  
  181.             nSamples++;
  182.  
  183.             if ( (nSamples & 0xFFF) == 1 ) {
  184.                 // Get a new block header
  185.                 for ( int i = 0; i < sn; i++ ) {
  186.  
  187.                     *dst++ = (short)(valpred[i] = GetSBits(16));
  188.  
  189.                     // The first sample in a block does not have a delta
  190.                     index[i] = (int)GetBits(6);
  191.                 }
  192.             } else {
  193.                 // Process a delta value
  194.                 for ( int i = 0; i < sn; i++ ) {
  195.                     int delta = (int)GetBits(nBits);
  196.  
  197.                     // Compute difference and new predicted value
  198.                     // Computes 'vpdiff = (delta+0.5)*step/4'
  199.  
  200.                     int step = stepsizeTable[index[i]];
  201.                     long vpdiff = 0;
  202.                     int k = k0;
  203.  
  204.                     do {
  205.                         if ( delta & k ) vpdiff += step;
  206.                         step >>= 1;
  207.                         k >>= 1;
  208.                     } while ( k );
  209.                     vpdiff += step; // add 0.5
  210.  
  211.  
  212.                     if ( delta & signmask ) // the sign bit
  213.                         valpred[i] -= vpdiff;
  214.                     else
  215.                         valpred[i] += vpdiff;
  216.  
  217.                     // Find new index value
  218.                     index[i] += indexTable[delta&(~signmask)];
  219.  
  220.                     if ( index[i] < 0 )
  221.                         index[i] = 0;
  222.                     else if ( index[i] > 88 )
  223.                         index[i] = 88;
  224.  
  225.                     // clamp output value
  226.                     if ( valpred[i] != (short)valpred[i] )
  227.                         valpred[i] = valpred[i] < 0 ? -32768 : 32767;
  228.  
  229.                     /* Step 7 - Output value */
  230.                     *dst++ = (short)valpred[i];
  231.                 }
  232.             }
  233.         }
  234.     }
  235. }
  236.